import { Component, _decorator, Node, UITransform, Color, Tween, Vec2, tween, v3, v2, Vec3, Widget, Layers, SpriteFrame, Sprite, AudioClip } from "cc";
import Water, { WaterInfo } from "./water";
import { WaterFlow } from "./waterFlow";
import { EDITOR } from "cc/env";
import { AnimationTime, defaultColor } from "../enum/Enums";
import { _CupTopInfo } from "../interfaces/BaseInter";
import { bdlMgr } from "db://assets/Script/Manager/BundleManager_S";
import { SSS_Consts } from "db://assets/Script/Data/SSS_Consts";
import { SSS_AudioManager } from "db://assets/Script/Manager/SSS_AudioManager";
import DaoShuiPaiXu_GameManager from "../DaoShuiPaiXu_GameManager";
import { DaoShuiPaiXu_GameData } from "../Data/DaoShuiPaiXu_GameData";

const { ccclass, property } = _decorator;

// 好看，区分度高
export let WaterColors = [
    "#", // 0代表空位没用，id从1开始



    // 第一阶段：高区分度基础色
    "#2196F3", // 亮蓝
    "#E91E63", // 粉红 (与亮红相近)
    "#ACC363", // 酸橙(绿)
    "#FFEB3B", // 亮黄
    "#08AA00", // 绿色

    "#673AB7", // 深紫
    "#FDF6E3", // 香草白 - 略带蜂蜜色调，温暖而明亮，带来阳光感
    "#795548", // 棕色
    "#3F51B5", // 靛蓝
    "#F44336", // 亮红

    "#29E7D6", // 青绿蓝
    "#E1BEE7", // 浅紫
    "#BDBDBD", // 中灰
    "#FFB74D", // 橙黄 (与琥珀黄相近)


    // 14个颜色--------------------------------------------------------

    // "#3E2723", // 黑棕

    // "#FFECB3", // 浅黄

    // 第三阶段：中性色和深色
    // "#FFCCBC", // 浅橙

    // "#212121", // 近黑

    // "#9C27B0", // 紫色
    // "#EF0031", // 大红
    // "#5D4037", // 深棕

    // "#8BC34A", // 酸橙(绿)
    // "#FF34E7", // 粉紫
    // "#FF8A65", // 浅珊瑚 (与亮红相近)
    // "#009688", // Teal青
    // "#00BCD4", // 青蓝
    // "#FFD54F", // 琥珀黄
    // "#4CAF50", // 绿色

    // 第二阶段：相近色变体
    // "#CDDC39", // 黄绿 (与酸橙相近)
    // "#03A9F4", // 天蓝 (与亮蓝相近)
    // "#FFFEF5", // 奶白 - 像新鲜牛奶，带一丝温暖的黄调，柔和甜美
    // "#F8F0E3", // 奶油白 - 比奶白更深，如同打发奶油，质感醇厚
    // "#FAF4E3", // 拿铁奶白 - 略带咖啡调的奶白，温暖而高级
    // "#FFFBF0", // 轻奶白 - 更接近纯白的奶色，轻盈不腻
    // "#DEB887", // 幽灵白 - 极浅的灰蓝色调
    // "#F5F5F5", // 白灰
]

// export let WaterColors = [
//     "#", // 0代表空位没用，id从1开始

//     "#FFFF00", // 纯黄
//     "#FFC107", // 琥珀色
//     "#FF9800", // 橙色
//     "#FF5722", // 深橙红
//     "#F44336", // 红色
//     "#E91E63", // 粉红
//     "#9C27B0", // 紫色
//     "#673AB7", // 深紫
//     "#3F51B5", // 靛蓝
//     "#2196F3", // 蓝色
//     "#00BCD4", // 青色
//     "#009688", // 青绿
//     "#4CAF50", // 绿色
//     "#8BC34A", // 黄绿
//     "#CDDC39", // 酸橙黄
//     "#FFEB3B", // 亮黄
//     "#FF6D00", // 深橙
//     "#FFCCBC", // 浅橙 (交替)
//     "#795548", // 棕色
//     "#E1BEE7", // 浅紫 (交替)
//     "#3E2723", // 深棕
//     "#FFFFFF", // 纯白 (交替)
//     "#000000", // 纯黑
//     "#9E9E9E"

//     // "#FFF9C4", // 浅黄 (更亮)
//     // "#FFD740", // 琥珀黄 (更饱和)
//     // "#FF9800", // 橙色 (更鲜明)
//     // "#FF5722", // 深橙红 (增强对比)
//     // "#F44336", // 亮红 (保持)
//     // "#E91E63", // 粉红 (保持)
//     // "#9C27B0", // 紫色 (保持)
//     // "#673AB7", // 深紫 (保持)
//     // "#3F51B5", // 靛蓝 (保持)
//     // "#2196F3", // 亮蓝 (保持)
//     // "#00BCD4", // 青蓝 (保持)
//     // "#009688", // Teal青 (保持)
//     // "#4CAF50", // 绿色 (保持)
//     // "#8BC34A", // 酸橙 (调整色相)
//     // "#CDDC39", // 黄绿 (调整亮度)
//     // "#FFEB3B", // 亮黄 (保持)
//     // "#FF6D00", // 深橙 (替换棕色)
//     // "#FFCCBC", // 浅橙 (交替)
//     // "#5D4037", // 深棕 (保持)
//     // "#E1BEE7", // 浅紫 (交替)
//     // "#3E2723", // 黑棕 (保持)
//     // "#F5F5F5", // 白灰 (交替)
//     // "#212121", // 近黑 (保持)
//     // "#BDBDBD"
// ]


// 2048
// export let WaterColors = [
//     "#", // 0代表空位没用，id从1开始

//     "#FFF3E7", // 浅杏色
//     "#FFEBCE", // 浅奶油色
//     "#FFC773", // 浅橙色
//     "#FFA663", // 珊瑚橙
//     "#FF8652", // 鲜橙色
//     "#FF5D52", // 亮红色
//     "#C6CB7B", // 橄榄绿
//     "#94CF94", // 浅绿色
//     "#5ACFAD", // 青绿色
//     "#52B6CF", // 天蓝色
//     "#528BCF", // 钴蓝色
//     "#7B7BCB", // 紫蓝色
//     "#9D5ACF", // 紫罗兰色
//     "#CF5AA7", // 紫红色
//     "#CF5A84", // 玫瑰粉
//     "#CF406A", // 亮玫红
//     "#AF2E5A", // 深玫红
//     "#8B1A4A", // 酒红色
//     "#F0D7E7", // 浅粉白
//     "#6C123B", // 深酒红
//     "#E4E1F8", // 浅紫灰
//     "#52102F", // 黑红紫
//     "#F4F4F4", // 银灰白
//     "#290918", // 黑红色
//     "#EDE8F6" // 淡紫色
// ]


// export let WaterColors = [
//     "#155DEF",

//     "#EF0031", //红
//     "#0082CE", //蓝
//     "#FFCF00", //黄
//     "#08AA00", //绿
//     "#FF34E7", //紫

//     "#BCA6E3", //粉
//     "#E4584F", //橙
//     "#00B38A", //青
//     "#DD2E44", //红
//     "#E5C69A", //黄
//     "#65DC8E", //绿
//     "#B068F0", //紫
//     "#F010BF", //粉
//     "#538849", //青
// ]

// export let WaterColors = [
//     "#155DEF",
//     "#F2C90F",
//     "#BD2656",
//     "#F0791F",
//     "#454574",
//     "#FE2D26",
//     "#BCA6E3",
//     "#E4584F",
//     "#00B38A",
//     "#DD2E44",
//     "#E5C69A",
//     "#65DC8E",
//     "#B068F0",
//     "#F010BF",
//     "#538849",
// ]

/**高度乘数因子，满杯水只显示80% */
const HEIGHT_FACTOR = 0.8;

/**一杯水，分成四组四个颜色，0表示没有水 */
export interface _CupInfo {
    colorIds: Array<number>;//长度为4
}

const SPLIT_COUNT = 4;

@ccclass("CupImgs")
export class CupImgs {
    @property(SpriteFrame)
    tub: SpriteFrame = null;
    @property(SpriteFrame)
    mask: SpriteFrame = null;
}

@ccclass
export default class Cup extends Component {
    @property(Water)
    private water: Water = null;
    /** 杯子的信息 */
    private info: _CupInfo = null; //

    @property(Sprite)
    private tubeNode: Sprite = null;
    @property(Sprite)
    private maskNode: Sprite = null;
    @property([CupImgs])
    private cupImgs: CupImgs[] = [];

    changeImg(index: number) {
        index = (DaoShuiPaiXu_GameData.Get_level() - 1) % this.cupImgs.length;

        this.tubeNode.spriteFrame = this.cupImgs[index].tub;
        this.maskNode.spriteFrame = this.cupImgs[index].mask;
    }

    private _colors: string[] = [];
    private _default_color: string = "";
    setWaterColor(colors: string[] = WaterColors, default_color: string = defaultColor) {
        this._colors = colors;
        this._default_color = default_color;
    }
    onLoad() {
        this.setWaterColor()

        this.node.on(Node.EventType.TOUCH_END, this.onBtn_click, this);

    }
    initWater() {
        const info = this.info;
        let arr = [];
        for (let i = SPLIT_COUNT - 1; i >= 0; i--) {
            let colorId = info.colorIds[i];
            if (colorId == 0) {
                continue;
            }
            let lastObj = arr[arr.length - 1];
            if (!lastObj || lastObj != colorId) {
                arr.push({
                    height: 1 / SPLIT_COUNT,
                    colorId: colorId
                });
            } else {
                lastObj.height += 1 / SPLIT_COUNT;
            }
        }
        arr.forEach(function (obj) {
            let hex = WaterColors[obj.colorId] || "#538849"
            // log("obj.colorId",obj.colorId,"color",hex)
            obj.color = new Color().fromHEX(hex);
            obj.height *= HEIGHT_FACTOR;
        })

        this.water.initInfos(arr);
    }
    // info: _CupInfo = null;
    setCupInfo(info: _CupInfo) {
        // setCupInfo(info: _CupInfo, onClick: (c: Cup) => void) {
        this.info = info;
        // this.onClick = onClick;

        this.initWater();
        // this.reset();
    }

    update() {
        // 如果当前处于编辑器模式，则直接返回，不进行后续操作。
        if (EDITOR) {
            return;
        }

        // 如果当前节点的旋转角度与水的 skewAngle 属性值相同，则直接返回，不进行后续操作。
        if (this.water.tiltAngle == this.node.angle) {
            return;
        }

        // 将当前节点的旋转角度赋值给水的 skewAngle 属性，以便在着色器中使用。
        this.water.tiltAngle = this.node.angle;
    }
    /**
   * 是否完成了（同颜色填满整个杯子）
   *  */
    checkIsFinshed() {
        /** 完成状态 */
        let finishedState = true; // 完成状态，默认为 true
        /** 颜色 */
        let colorIds = this.info.colorIds; // 获取颜色编号数组
        /** 颜色编号 */
        let tmpId = null; // 临时颜色编号
        /** 空数量 */
        let empTyNum = 0; // 空的分割点数量
        for (let i = 0; i < SPLIT_COUNT; i++) {
            // 遍历分割点
            if (tmpId == null) {
                // 如果临时颜色编号为 null，则将其设置为当前颜色编号
                tmpId = colorIds[i];
            }
            if (tmpId != colorIds[i]) {
                // 如果当前颜色编号与临时颜色编号不同，则表示未完成
                finishedState = false;
                break;
            } else if (colorIds[i] == 0) {
                // 如果当前颜色编号为 0，则表示当前分割点为空
                empTyNum++;
            }
        }
        if (empTyNum == SPLIT_COUNT) {
            // 如果所有分割点都为空，则表示已完成
            finishedState = true;
        }
        return finishedState; // 返回完成状态
    }
    setStartAddWater(colorId: number, num: number) {
        let acc = 0; // 计数器，记录已经添加的数量
        for (let i = SPLIT_COUNT - 1; i >= 0; i--) {
            // 从后往前遍历分割点
            if (this.info.colorIds[i] != 0) {
                // 如果当前分割点已经有颜色了，则跳过
                continue;
            }
            this.info.colorIds[i] = colorId; // 将颜色编号赋值给当前分割点
            if (++acc == num) {
                // 如果已经添加了指定数量的颜色，则跳出循环
                break;
            }
        }
    }

    /**
   * 开始添加水的方法
   * @param colorId  颜色编号
   * @param num 添加的数量
   */
    startAddWater(colorId: number, num: number) {
        let hex = this._colors[colorId] || this._default_color; // 获取颜色的十六进制表示，如果没有则使用默认颜色
        this.water.addInfo({
            // 调用水的实例的 addInfo 方法，添加水的信息
            colorId: colorId, // 颜色编号
            height: (num / SPLIT_COUNT) * HEIGHT_FACTOR, // 高度
            color: new Color().fromHEX(hex), // 颜色
        });

        // UtilAudio.pourWater_effect_play(num / SPLIT_COUNT);
        // AudioMgr.ins.playSoundAtTime(Clips.pourWater, num / SPLIT_COUNT);

        let audio_root = `audio/倒水`;
        bdlMgr.getRes<AudioClip>(SSS_Consts.BundleName.AUDIO, audio_root, AudioClip).then(res => {
            SSS_AudioManager.Instance.playSoundWithControl(res, 0.4, DaoShuiPaiXu_GameManager.Instance.node);
        });
    }

    private tween: Tween = null;

    /**
       * 初始位置
       */
    private _orignPt: Vec3 = null;
    get orignPt() {
        return this._orignPt;
    }

    setOrignPt(pt: Vec3) {
        this._orignPt = pt;
    }

    /**
       * 设置倾倒水的锚点
       * @param isRight 是否从右侧倾倒水
       */
    public setPourAnchor(isRight: boolean) {
        // 创建一个向量表示锚点的位置(选一个靠上一点的位置)
        let pt = v2(3, 2);
        // 如果从右侧倾倒水，则将锚点的 x 坐标设置为杯子宽度减去 3，否则保持不变
        pt.x = isRight ? this.node.getComponent(UITransform).width - pt.x : pt.x;
        // 将锚点的 y 坐标设置为杯子高度减去 2，以将其从杯子的顶部向下移动一些距离
        pt.y = this.node.getComponent(UITransform).height - pt.y;

        // 将锚点的 x 和 y 坐标分别除以杯子的宽度和高度，以将它们转换为相对于杯子节点的锚点坐标
        pt.x = pt.x / this.node.getComponent(UITransform).width;
        pt.y = pt.y / this.node.getComponent(UITransform).height;

        // 调用 setAnchor() 方法设置杯子节点的锚点
        this.setAnchor(pt);
    }
    /**
   * 设置锚点位置
   * @param anchor 锚点位置
   */
    private setAnchor(anchor: Vec2): void {
        let trans = this.node.getComponent(UITransform)

        // 获取旧的锚点位置
        // let oldAnchor = this.node.getAnchorPoint();
        let oldAnchor = trans.anchorPoint.clone()
        // 获取当前节点的世界坐标
        let selfPt = this.node.getPosition();
        // 获取水的世界坐标
        let waterPt = this.water.node.getPosition();

        // 设置新的锚点位置
        // this.node.setAnchorPoint(anchor);
        trans.setAnchorPoint(anchor);

        // 计算锚点位置的偏移量
        let offsetAnchor = v2(anchor.x - oldAnchor.x, anchor.y - oldAnchor.y);
        // 计算偏移后的节点坐标
        let offsetPt = v2(
            offsetAnchor.x * this.node.getComponent(UITransform).width,
            offsetAnchor.y * this.node.getComponent(UITransform).height
        );
        // 将偏移后的节点坐标旋转
        offsetPt = rotatePt(offsetPt, this.node.angle);
        // 更新节点的位置
        selfPt.x += offsetPt.x;
        selfPt.y += offsetPt.y;
        this.node.setPosition(selfPt);

        // 更新水的位置
        waterPt.x -= offsetAnchor.x * this.node.getComponent(UITransform).width;
        waterPt.y -= offsetAnchor.y * this.node.getComponent(UITransform).height;
        this.water.node.setPosition(waterPt);
    }

    /**
   * 移动杯子并倾倒水
   * Move the cup and pour out the water
   * @param dstPt 倾倒水的目标点
   * @param isRight 是否向右倾倒
   * @param num 倾倒的数量
   */
    moveToPour(dstPt: Vec2, isRight: boolean, num: number) {
        let startAngle = this.water.getPourStartAngle(); // 获取倾倒开始时的角度
        let endAngle = this.water.getPourEndAngle(); // 获取倾倒结束时的角度
        this.water.onStartPour(num); // 开始倾倒水

        if (isRight) {
            startAngle *= -1; // 如果向右倾倒，则将开始角度取反
            endAngle *= -1; // 如果向右倾倒，则将结束角度取反
        }

        // this.setOrignPt(this.node.position); // 设置初始位置

        let moveDur = AnimationTime.moveTime; // 移动持续时间
        let pourDur = AnimationTime.pourTime; // 倾倒持续时间
        this.tween = tween(this.node)
            .set({ angle: 0 }) // 设置初始角度为0
            // .to(moveDur, { x: dstPt.x, y: dstPt.y, angle: startAngle }) // 移动到目标点并设置开始角度
            .to(moveDur, { position: v3(dstPt.x, dstPt.y), angle: startAngle })
            .to(pourDur, { angle: endAngle }) // 倾倒水并设置结束角度
            .call(() => {
                this.tween = null; // 动画完成后将tween设置为null
            })
            .start();
        this.pourSameColor(num);
    }
    // 动画回到初始位置
    backToInitPos() {
        if (this.tween) {
            // 如果当前正在播放动画，则停止动画
            this.tween.stop();
            this.tween = null;
        }
        this.tween = tween(this.node)
            .to(AnimationTime.moveTime, { position: this._orignPt, angle: 0 }) // 回到初始位置
            .call(() => {
                this.tween = null; // 动画完成后将tween设置为null
                // this.changeCheckedState(); // 改变选中状态TODO:
            })
            .start();
    }

    private _upInfo: _CupTopInfo = null;
    get upCupInfo() {
        return this._upInfo;
    }

    /**
  * 倒掉相同颜色的水
  */
    pourSameColor(num: number) {
        let count = 0;
        let top = this.getTop(); // 获取杯子顶部的水
        let colorIds = this.info.colorIds; // 获取杯子中的颜色ID数组
        this._upInfo = JSON.parse(JSON.stringify(top));
        for (let i = 0; i < SPLIT_COUNT; i++) {
            let _id = colorIds[i];
            if (_id == 0) {
                // 如果颜色ID为0，则跳过
                continue;
            } else if (top.topColorId == _id) {
                // 如果顶部的颜色ID与当前颜色ID相同，则将当前颜色ID设置为0
                if (count++ == num) break;
                colorIds[i] = 0;
            } else {
                break; // 如果顶部的颜色ID与当前颜色ID不同，则跳出循环
            }
        }
    }

    /**
   * 获取杯子顶部的水
   * Get the top water of the cup
   */
    getTop(): _CupTopInfo {
        /** 获取杯子中的颜色ID数组 */
        let colorIds = this.info.colorIds; //
        /** 杯顶的空位有几格 */
        let emptyNum = 0; //
        /** 杯顶颜色id */
        let topColorId = 0; //
        /** 杯顶的颜色共有几格 */
        let topColorNum = 0; //
        for (let i = 0; i < SPLIT_COUNT; i++) {
            // 遍历颜色ID数组
            if (colorIds[i] == 0) {
                // 如果颜色ID为0，则表示该位置为空
                emptyNum++; // 空位数量加1
                continue;
            }
            if (topColorId == 0 || topColorId == colorIds[i]) {
                // 如果杯顶颜色ID为0或者与当前颜色ID相同
                topColorId = colorIds[i]; // 将杯顶颜色ID设置为当前颜色ID
                topColorNum++; // 杯顶颜色数量加1
            } else {
                break; // 如果杯顶颜色ID与当前颜色ID不同，则跳出循环
            }
        }
        return {
            /** 返回空位数量 */
            emptyNum: emptyNum, //
            /** 返回杯顶颜色ID */
            topColorId: topColorId, //
            /** 返回杯顶颜色数量 */
            topColorNum, //
            /** 返回杯顶颜色的十六进制表示，如果颜色ID无效，则返回默认颜色 */
            colorHex: this._colors[topColorId] || this._default_color //
        };
    }

    // 获取瓶口的中心位置
    getBottleMouthCenter() {
        // 局部坐标转世界坐标
        // let pos = this.node.convertToWorldSpaceAR(
        //   cc.v2(this.node.width / 2, this.node.height)
        // );
        return {
            x: this.node.position.x,
            y: this.node.position.y + this.node.getComponent(UITransform).width / 2,
        };
        // 世界坐标转局部坐标
    }

    /**
   * 选中状态
   */
    checked: boolean;
    private onClick: (c: Cup) => void = null;

    setOnClick(onClick: (c: Cup) => void) {
        this.onClick = onClick;
    }

    /**
  * 改变选中状态
  * @param _event
  * @param state
  */
    public changeCheckedState() {
        if (this.isPouring()) {
            return;
        }
        if (this.onClick) {
            this.onClick(this);
        }
    }

    /**
   * 检查杯子当前是否正在倾倒
   * @returns {boolean} 如果杯子正在倾倒，则为true，否则为false
   */
    public isPouring() {
        return Math.abs(this.node.angle) > 1.0;
    }

    /**
   * 获取当前水面的global y坐标 */
    getWaterSurfacePosY(needAdjust = false) {
        let top = this.getTop();
        let y = (SPLIT_COUNT - top.emptyNum) / SPLIT_COUNT;
        if (y < 0.02) {
            y = 0.02;
        } else if (needAdjust) {
            y -= (1.0 / SPLIT_COUNT) * HEIGHT_FACTOR;
        }
        y *= HEIGHT_FACTOR;
        y -= 0.5;
        let pt = v3(0, this.water.node.getComponent(UITransform).height * y);
        pt = this.water.node.getComponent(UITransform).convertToWorldSpaceAR(pt);
        return pt.y;
    }

    /**
   * 倒水结束回调
   * @param onFinish 倒水结束回调
   */
    setPourInCallback(onFinish: (cup: Cup, isFInish: boolean) => void) {
        //水倒完了
        const _onFinish = () => {
            this._upInfo = null;
            let isFinished = this.checkIsFinshed();
            // cc.log("-----------isFinished",isFinished)
            if (onFinish) {
                onFinish(this, isFinished);
            }
            if (isFinished) {
                // AudioMgr.ins.playSound(Clips.ContainerFinish, 0.3);
            }
        };
        this.water.setPourInCallback(_onFinish.bind(this));
    }
    /**
   * 倒水开始回调
   */
    setPourOutCallback(pourStart: (c: Cup) => void, pourEnd: (c: Cup) => void) {
        //水开始从瓶口流出来
        const _onStart = function () {
            if (pourStart) {
                pourStart(this);
            }
        };
        //水倒完了
        const _onFinish = function () {
            if (this.tween) {
                this.tween.stop();
                this.tween = null;
            }
            if (pourEnd) {
                pourEnd(this);
            }
        };
        this.water.setPourOutCallback(_onStart.bind(this), _onFinish.bind(this));
    }
    public setNormalAnchor() {
        this.setAnchor(v2(0.5, 0.5));
    }

    /**
   * 立刻向杯子中添加水
   * @param colorId 颜色编号
   * @param num 添加的水的数量
   */
    addWaterImmediately(colorId: number, num: number) {
        let acc = 0;
        // 从后往前遍历 colorIds 数组
        for (let i = SPLIT_COUNT - 1; i >= 0; i--) {
            // 如果当前位置已经有颜色，则跳过
            if (this.info.colorIds[i] != 0) {
                continue;
            }
            // 否则将当前位置的颜色设置为 colorId
            this.info.colorIds[i] = colorId;
            // 如果已经添加了 num 滴水，则退出循环
            if (++acc == num) {
                break;
            }
        }
        // 初始化水的状态
        this.initWater();
    }

    /**
   * 立刻从杯子中移除水
   * @param num 移除的水的数量
   * @returns 移除的水的信息
   */
    removeTopWaterImmediately(num: number) {
        let acc = 0;
        // 获取杯子中最上面的水
        let top = this.getTop();
        let colorIds = this.info.colorIds;
        // 从前往后遍历 colorIds 数组
        for (let i = 0; i < SPLIT_COUNT; i++) {
            let _id = colorIds[i];
            // 如果当前位置没有颜色，则跳过
            if (_id == 0) {
                continue;
                // 如果当前位置的颜色与最上面的水的颜色相同，则将当前位置的颜色设置为 0
            } else if (top.topColorId == _id) {
                colorIds[i] = 0;
                // 如果已经移除了 num 滴水，则退出循环
                if (++acc >= num) {
                    break;
                }
            } else {
                break;
            }
        }
        // 初始化水的状态
        this.initWater();
        return top;
    }

    // -----------------------------------------------

    private _flow: WaterFlow = null;
    public getFlow(): WaterFlow {
        if (this._flow) {
            return this._flow;
        }
        let _node = new Node("water_flow");
        _node.layer = Layers.Enum.UI_2D
        _node.addComponent(UITransform)
        this._flow = _node.addComponent(WaterFlow);
        return this._flow;
    }

    // private onClick: (c: Cup) => void = null;

    onBtn_click() {
        if (this.isPouring()) {
            return;
        }
        if (this.onClick) {
            this.onClick(this);
        }
    }

    // private tween: Tween<Node> = null;
    /**
     * 移动到目标点、旋转瓶子并倒水
     * @param isRight 倾斜角度，向左为正，右为负
     * @param onPourStart 水开始从瓶口流出来
     * @param onPourEnd 本次水倒完了
     */
}

function rotatePt(pt: Vec2, angle: number) {
    let radian = angle2radian(angle);
    let ret = v2();
    ret.x = pt.x * Math.cos(radian) - pt.y * Math.sin(radian);
    ret.y = pt.x * Math.sin(radian) + pt.y * Math.cos(radian);

    return ret;
}

function angle2radian(angle: number) {
    while (angle > 360) {
        angle -= 360;
    }
    while (angle < -360) {
        angle += 360;
    }
    return (angle % 360) * Math.PI / 180.0;
}